Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4360 +/- ##
=======================================
Coverage 98.87% 98.88%
=======================================
Files 59 59
Lines 12299 12357 +58
Branches 2342 2350 +8
=======================================
+ Hits 12161 12219 +58
Misses 68 68
Partials 70 70 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| self._is_sorted = False | ||
| self._pending: list[tuple[str, Any]] = [] | ||
|
|
||
| def _update(self, array: list[Any]) -> None: |
There was a problem hiding this comment.
Are we able to avoid the name array here, as this is a stdlib module as well?
There was a problem hiding this comment.
Renamed it to names.
| _NAMED_DESTINATION_INDEX_MINIMUM = 32 | ||
|
|
||
|
|
||
| class _NamedDestinationIndex: |
There was a problem hiding this comment.
Would there be any benefits to subclass list or similar here and re-use the common API?
There was a problem hiding this comment.
I don't think it would help much: the index doesn't own the /Names array, the ArrayObject stays in the document and the index only sits next to it during one merge(). A list subclass would mean swapping that object in the document, while add_named_destination_array() and get_named_dest_root() keep working on the original. Happy to change it if you see a cleaner way.
merge()adds the named destinations of the appended document one at a time. For each one it checkstitle in namesand thenadd_named_destination_array()scans the array again to find where to insert, so a document with many named destinations takes quadratic time.For documents with at least 32 named destinations, the string entries now go into a set for the lookup. If the existing keys are sorted, the new destinations are collected and sorted into the array once at the end. Putting each one before the first greater key, as
add_named_destination_array()does, gives the same order as that stable sort. Arrays with unsorted keys still use the old insertion, and documents with fewer destinations keep the old code, since building the index reads the whole array.writer.append(reader)with all destinations on one page:The resulting
/Namesarrays and written files are the same as on main in about 1,300 generated cases (unsorted and odd-length arrays, indirect arrays, byte string keys,clone_fromwriters, appending the same file twice), and appending many small documents into a large array is as fast as before.AI assistance: Claude Code (Claude Opus 5.5) helped write and measure this, and Codex (GPT-6 Astra) reviewed it. I reviewed the change and ran the test suite.